---@class orm数据队形的基类
local _fac = class('ORMBase')
-- ==========================
--default params
local d = Ding
local Logger = d.Logger
local PoolMgr = d.PoolMgr
-- ==========================
--dc和处理的实例脚本映射
local DCTYPE_SRC_MAPPING = {
    mysql = 'framework.db.mysqlinc',
    redis = 'framework.db.redisinc'
}
--[[
    ~dccfg 格式
    dccfg = {
        ctype = "mysql",
        host = '39.100.149.120',
        user = 'root',
        password = 'aA.76366151',
        database = 'water_admin',
        charset = "utf8",
        tbname = 'auth'
    }
]]

function _fac:ctor(dccfg)
    self._dccfg = dccfg

    --lazy init func 
    local func_name 
    for funck, val in pairs(dccfg) do 
        func_name = "cfg_"..funck
        if not self[funck] then 
            self[func_name] = function(self)
                return val or ''
            end
        end 
    end

    self._mname = modelname
    self._model = nil
end

function _fac:_dc()
    local dc_type = self._dccfg['ctype'] or 'mysql'
    return PoolMgr:get_connect(DCTYPE_SRC_MAPPING[dc_type], self._dccfg)
end

function _fac:_dc_runcmd(funcname, ...)
    local dc = self:_dc()
    if not dc then 
        Logger:error("Get dc connect [<ip>=%s, <dctype>=%s] failed!", self:cfg_host(), self:cfg_ctype())
        return false
    end 
    return dc[funcname](dc, ...)
end

function _fac:new_insert(...)
    local params = {...}
    local n_model = self:new_model(unpack(params))
    if (not n_model) then
        Logger:warning('[orm base]:new_model return is empty!chk it!')
        return false
    end
    self._model = n_model
    Logger:dump(n_model, string.format('[%s]omr new insert', self:cfg_ctype()))
    return self:_dc_runcmd('insert_data', self:cfg_tbname(), n_model)
end

function _fac:new_insert_with_tbname(tbname, ...)
    local params = {...}
    local n_model = self:new_model(unpack(params))
    if (not n_model) then
        Logger:warning('[orm base]:new_model return is empty!chk it!')
        return false
    end
    self._model = n_model
    Logger:dump(n_model, string.format('[%s]omr new insert', self:cfg_ctype()))
    return self:_dc_runcmd('insert_data', tbname, n_model)
end

function _fac:update(valdic, condic, ...)
    return self:_dc_runcmd('update', self:cfg_tbname(), valdic, condic, ...)
end

function _fac:update_with_tbname(tbname, valdic, condic, ...)
    return self:_dc_runcmd('update', tbname, valdic, condic, ...)
end 

function _fac:update_force(valdic, condic)
    local val = self:find(condic)
    if not val then 
        return self:new_insert(unpack(valdic))
    end
    return self:update(valdic, condic)
end

function _fac:new_model()
end

function _fac:get_model()
    return self._model
end

function _fac:find(lcond)
    if (#self:cfg_tbname() == 0) then
        Logger:warning('[REDISINC]find_one params <kname> is empey!')
    end
    return self:_dc_runcmd('find_one', self:cfg_tbname(), lcond)
end

function _fac:find_all(lcond)
    if (#self:cfg_tbname() == 0) then
        Logger:warning('[REDISINC]find_one params <kname> is empey!')
    end
    return self:_dc_runcmd('find_all', self:cfg_tbname(), lcond)
end

function _fac:find_all_with_tbname(tbname, lcond)
    return self:_dc_runcmd('find_all', tbname, lcond)
end

function _fac:find_in_set_with_tbname(tbname, key, vlist) 
    return self:_dc_runcmd('find_in_set', tbname, key, vlist)
end

function _fac:find_in_set(key, vlist) 
    return self:_dc_runcmd('find_in_set', self:cfg_tbname(), key, vlist)
end

function _fac:find_in(key, vlist) 
    return self:_dc_runcmd('find_in', self:cfg_tbname(), key, vlist)
end

--- 获取限制的条数内容
-- 从数据库中默认排序获取指定条数
-- @tparam  table self
-- @tparam  number min 最小标记
-- @tparam  number max 最大标记
function _fac:get_limitcnt(min, max)
    return self:_dc_runcmd('fetch_limitcnt', self:cfg_tbname(), min, max)
end

--- 获取限制的条数内容
-- 从数据库中默认排序获取指定条数
-- @tparam  table self
-- @tparam  number min 最小标记
-- @tparam  number max 最大标记
function _fac:get_limitcnt_with_tbname(tbname, min, max)
    return self:_dc_runcmd('fetch_limitcnt', tbname, min, max)
end

--- 删除数据
-- 从默认tbname中删除一条数据
-- @tparam  table self
-- @tparam  string pname 数据的key
-- @treturn any 是否删除成功
function _fac:dele_one(condorpname)
    return self:_dc_runcmd('dele_one', self:cfg_tbname(), condorpname)
end

--- 删除数据 by $tbname
-- 从制定tbname中删除一条数据
-- @tparam  table self
-- @tparam  string tbname 制定的tbname
-- @tparam  string pname 删除的tbname的key
-- @treturn any 是否删除成功.
function _fac:dele_one_with_tbname(tbname, condorpname)
    return self:_dc_runcmd('dele_one', tbname, condorpname)
end

--[[ ================REDIS ONLY================= ]]
function _fac:_chk_dc_isredis()
    local isredis = self._dccfg['ctype'] == 'redis'
    if not isredis then
        Logger:warning("the api is only in ctype='redis', other type funciton will do nothing!")
    end
    return isredis
end

function _fac:list_insert(tbname, val)
    if not self:_chk_dc_isredis() then
        return
    end
    return self:_dc_runcmd('list_insert', tbname, val)
end

function _fac:list_len(tbname)
    if not self:_chk_dc_isredis() then
        return
    end
end

function _fac:list_pop(tbname)
    if not self:_chk_dc_isredis() then
        return
    end
end

function _fac:list_push(tbname)
    if not self:_chk_dc_isredis() then
        return
    end
end

function _fac:list_index(tbname, index)
    if not self:_chk_dc_isredis() then
        return
    end
end

--[[ ================REDIS ONLY================= ]]
return _fac
